package cas.ihep.fs.hdfs;

import org.apache.hadoop.hdfs.DFSClient;
import org.apache.hadoop.hdfs.DFSOutputStream;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

class DFSClientAdapter {
    private DFSClientAdapter(){}
    static String clientName(DFSClient dfsClient){
        try{
            return (String) _clientName.get(dfsClient);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }

    static boolean clientRunning(DFSClient dfsClient){
        try{
            return _clientRunning.getBoolean(dfsClient);
        }catch (IllegalAccessException e){
            throw new RuntimeException(e);
        }
    }

    static void beginFileLease(DFSClient dfsClient,long id){
        try{
            _beginFileLease.invoke(dfsClient,id,null);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        } catch (InvocationTargetException e) {
            Throwable target=e.getTargetException();
            if(target instanceof RuntimeException){
                throw (RuntimeException)target;
            }else{
                throw new RuntimeException(target);
            }
        }
    }

    static void endFileLease(DFSClient dfsClient,long id){
        try{
            _endFileLease.invoke(dfsClient,id);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        } catch (InvocationTargetException e) {
            Throwable target=e.getTargetException();
            if(target instanceof RuntimeException){
                throw (RuntimeException)target;
            }else{
                throw new RuntimeException(target);
            }
        }
    }

    private static final Field _clientName,_clientRunning;
    private static final Method _beginFileLease,_endFileLease;
    static {
        Class<DFSClient> dfsClientClass=DFSClient.class;
        try{
            _clientName=dfsClientClass.getDeclaredField("clientName");
            _clientRunning=dfsClientClass.getDeclaredField("clientRunning");
            _clientName.setAccessible(true);
            _clientRunning.setAccessible(true);
            _beginFileLease=dfsClientClass.getDeclaredMethod("beginFileLease", long.class, DFSOutputStream.class);
            _beginFileLease.setAccessible(true);
            _endFileLease=dfsClientClass.getDeclaredMethod("endFileLease", long.class);
            _endFileLease.setAccessible(true);
        }catch (NoSuchFieldException | NoSuchMethodException e){
            throw new RuntimeException(e);
        }
    }
}
